package com.shrct.businessprocess.project.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.budget.impl.RCBudgetImpl;
import com.shrct.businessprocess.project.RCActualCostReport;
import com.shrct.businessprocess.project.RCActualCostReportItem;
import com.shrct.businessprocess.project.RCCost4ACTItemSnap;
import com.shrct.businessprocess.project.RCCost4RemainItemSnap;
import com.shrct.businessprocess.project.RCProjectMoney;
import com.shrct.businessprocess.project.impl.RCActualCostReportImpl;
import com.shrct.businessprocess.project.impl.RCCost4ACTItemSnapImpl;
import com.shrct.businessprocess.project.impl.RCCost4RemainItemSnapImpl;
import com.shrct.businessprocess.project.proxy.RCActualCostReportItemProxy;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCACTUALCOSTREPORTITEM_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rcactualcostreportitem")
public class RCActualCostReportItemImpl extends BaseModelObject implements RCActualCostReportItem {
  public RCActualCostReportItemImpl() {
    super();
  }
  
  public RCActualCostReportItemImpl(final RCActualCostReport report) {
    super();
    this.report = report;
  }
  
  @JoinColumn(name = "report_id")
  @ManyToOne(targetEntity = RCActualCostReportImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCActualCostReport report;
  
  public RCActualCostReport getReport() {
    return this.report;
  }
  
  public RCActualCostReportItem setReport(final RCActualCostReport report) {
    this.report = report;
    return this;			
    
  }
  
  @JoinColumn(name = "budget_id")
  @ManyToOne(targetEntity = RCBudgetImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCBudget budget;
  
  public RCBudget getBudget() {
    return this.budget;
  }
  
  public RCActualCostReportItem setBudget(final RCBudget budget) {
    this.budget = budget;
    return this;			
    
  }
  
  @JoinColumn(name = "prevItem_id")
  @ManyToOne(targetEntity = RCActualCostReportItemImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCActualCostReportItem prevItem;
  
  public RCActualCostReportItem getPrevItem() {
    return this.prevItem;
  }
  
  public RCActualCostReportItem setPrevItem(final RCActualCostReportItem prevItem) {
    this.prevItem = prevItem;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCCost4ACTItemSnapImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "reportItem")
  private Collection<RCCost4ACTItemSnap> cost4ActItemSnaps = new java.util.ArrayList<com.shrct.businessprocess.project.RCCost4ACTItemSnap>();;
  
  public Collection<RCCost4ACTItemSnap> getCost4ActItemSnaps() {
    return this.cost4ActItemSnaps;
  }
  
  public RCCost4ACTItemSnap createAndAddtoCost4ActItemSnaps() {
    getCost4ActItemSnaps().size();
    com.shrct.businessprocess.project.RCCost4ACTItemSnap rCCost4ACTItemSnap = new com.shrct.businessprocess.project.impl.RCCost4ACTItemSnapImpl(this);
    getObjectFactory().create(rCCost4ACTItemSnap);
    getCost4ActItemSnaps().add(rCCost4ACTItemSnap);
    return rCCost4ACTItemSnap;
    
  }
  
  public RCCost4ACTItemSnap createAndAddtoCost4ActItemSnaps(final Procedure1<RCCost4ACTItemSnap> updater) {
    getCost4ActItemSnaps().size();
    com.shrct.businessprocess.project.RCCost4ACTItemSnap rCCost4ACTItemSnap = new com.shrct.businessprocess.project.impl.RCCost4ACTItemSnapImpl(this);
    getObjectFactory().create(rCCost4ACTItemSnap);
    getCost4ActItemSnaps().add(rCCost4ACTItemSnap);
    return rCCost4ACTItemSnap;
    
  }
  
  public RCActualCostReportItem removeAllCost4ActItemSnaps() {
    for(RCCost4ACTItemSnap obj : this.cost4ActItemSnaps){
    	getObjectFactory().delete(obj);
    }
    this.cost4ActItemSnaps.clear();
    return this;	
    
  }
  
  public RCActualCostReportItem removeFromCost4ActItemSnaps(final RCCost4ACTItemSnap rCCost4ACTItemSnap) {
    this.cost4ActItemSnaps.remove(rCCost4ACTItemSnap);
    getObjectFactory().delete(rCCost4ACTItemSnap);
    return this;
    
  }
  
  @OneToMany(targetEntity = RCCost4RemainItemSnapImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "reportItem")
  private Collection<RCCost4RemainItemSnap> cost4RemainItemSnaps = new java.util.ArrayList<com.shrct.businessprocess.project.RCCost4RemainItemSnap>();;
  
  public Collection<RCCost4RemainItemSnap> getCost4RemainItemSnaps() {
    return this.cost4RemainItemSnaps;
  }
  
  public RCCost4RemainItemSnap createAndAddtoCost4RemainItemSnaps() {
    getCost4RemainItemSnaps().size();
    com.shrct.businessprocess.project.RCCost4RemainItemSnap rCCost4RemainItemSnap = new com.shrct.businessprocess.project.impl.RCCost4RemainItemSnapImpl(this);
    getObjectFactory().create(rCCost4RemainItemSnap);
    getCost4RemainItemSnaps().add(rCCost4RemainItemSnap);
    return rCCost4RemainItemSnap;
    
  }
  
  public RCCost4RemainItemSnap createAndAddtoCost4RemainItemSnaps(final Procedure1<RCCost4RemainItemSnap> updater) {
    getCost4RemainItemSnaps().size();
    com.shrct.businessprocess.project.RCCost4RemainItemSnap rCCost4RemainItemSnap = new com.shrct.businessprocess.project.impl.RCCost4RemainItemSnapImpl(this);
    getObjectFactory().create(rCCost4RemainItemSnap);
    getCost4RemainItemSnaps().add(rCCost4RemainItemSnap);
    return rCCost4RemainItemSnap;
    
  }
  
  public RCActualCostReportItem removeAllCost4RemainItemSnaps() {
    for(RCCost4RemainItemSnap obj : this.cost4RemainItemSnaps){
    	getObjectFactory().delete(obj);
    }
    this.cost4RemainItemSnaps.clear();
    return this;	
    
  }
  
  public RCActualCostReportItem removeFromCost4RemainItemSnaps(final RCCost4RemainItemSnap rCCost4RemainItemSnap) {
    this.cost4RemainItemSnaps.remove(rCCost4RemainItemSnap);
    getObjectFactory().delete(rCCost4RemainItemSnap);
    return this;
    
  }
  
  private Double totalIncomeAmount = Double.valueOf(0d);
  
  public Double getTotalIncomeAmount() {
    return this.totalIncomeAmount;
  }
  
  public RCActualCostReportItem setTotalIncomeAmount(final Double totalIncomeAmount) {
    this.totalIncomeAmount = totalIncomeAmount;
    return this;			
    
  }
  
  public Double calcTotalIncome() {
    RCProjectMoney _actualContractPrice = this.budget.getActualContractPrice();
    Double _hostAmount = _actualContractPrice.toHostAmount();
    Double _totalIncomePrecent = this.report.getTotalIncomePrecent();
    double _multiply = DoubleExtensions.operator_multiply(_hostAmount, _totalIncomePrecent);
    return Double.valueOf(_multiply);
  }
  
  private Double totalActualAmount = Double.valueOf(0d);
  
  public Double getTotalActualAmount() {
    return this.totalActualAmount;
  }
  
  public RCActualCostReportItem setTotalActualAmount(final Double totalActualAmount) {
    this.totalActualAmount = totalActualAmount;
    return this;			
    
  }
  
  public Double calcTotalActualAmount() {
    Double _totalIncomePrecent = this.report.getTotalIncomePrecent();
    RCProjectMoney _expectedCostAmount = this.budget.getExpectedCostAmount(_totalIncomePrecent);
    Double _hostAmount = _expectedCostAmount.toHostAmount();
    return _hostAmount;
  }
  
  public Double getTotalGrossProfit() {
    double _minus = DoubleExtensions.operator_minus(
      this.totalIncomeAmount, this.totalActualAmount);
    return Double.valueOf(_minus);
  }
  
  /**
   * 本次收入
   */
  public Double getIncomeAmount() {
    double _xblockexpression = (double) 0;
    {
      boolean _equals = Objects.equal(this.prevItem, null);
      if (_equals) {
        return this.totalIncomeAmount;
      }
      Double _totalIncomeAmount = this.prevItem.getTotalIncomeAmount();
      double _minus = DoubleExtensions.operator_minus(
        this.totalIncomeAmount, _totalIncomeAmount);
      _xblockexpression = (_minus);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  /**
   * 本次Actual Cost
   */
  public Double getActualAmount() {
    double _xblockexpression = (double) 0;
    {
      boolean _equals = Objects.equal(this.prevItem, null);
      if (_equals) {
        return this.totalActualAmount;
      }
      Double _totalActualAmount = this.prevItem.getTotalActualAmount();
      double _minus = DoubleExtensions.operator_minus(
        this.totalActualAmount, _totalActualAmount);
      _xblockexpression = (_minus);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  /**
   * 本次毛利
   */
  public Double getGrossProfit() {
    double _xblockexpression = (double) 0;
    {
      boolean _equals = Objects.equal(this.prevItem, null);
      if (_equals) {
        return this.getTotalGrossProfit();
      }
      Double _totalGrossProfit = this.getTotalGrossProfit();
      Double _totalGrossProfit_1 = this.prevItem.getTotalGrossProfit();
      double _minus = DoubleExtensions.operator_minus(_totalGrossProfit, _totalGrossProfit_1);
      _xblockexpression = (_minus);
    }
    return Double.valueOf(_xblockexpression);
  }
  
  public Boolean isEmptyResult() {
    boolean _and = false;
    Double _incomeAmount = this.getIncomeAmount();
    boolean _equals = ((_incomeAmount).doubleValue() == 0d);
    if (!_equals) {
      _and = false;
    } else {
      Double _actualAmount = this.getActualAmount();
      boolean _equals_1 = ((_actualAmount).doubleValue() == 0d);
      _and = (_equals && _equals_1);
    }
    return Boolean.valueOf(_and);
  }
  
  public void performCalculate() {
    Double _calcTotalIncome = this.calcTotalIncome();
    this.totalIncomeAmount = _calcTotalIncome;
    Double _calcTotalActualAmount = this.calcTotalActualAmount();
    this.totalActualAmount = _calcTotalActualAmount;
  }
  
  public static RCActualCostReportItem create(final RCActualCostReport report, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.project.RCActualCostReportItem rCActualCostReportItem = new com.shrct.businessprocess.project.impl.RCActualCostReportItemImpl(
    	report
    );
    objectFactory.create(rCActualCostReportItem);
    return rCActualCostReportItem;			
    
  }
  
  public static RCActualCostReportItem createRCActualCostReportItemImpl(final RCActualCostReport report, final IObjectFactory objectFactory, final Procedure1<RCActualCostReportItem> init) {
    com.shrct.businessprocess.project.RCActualCostReportItem rCActualCostReportItem = new com.shrct.businessprocess.project.impl.RCActualCostReportItemImpl(
    	report
    );
    objectFactory.create(rCActualCostReportItem);
    init.apply(rCActualCostReportItem);
    
    return rCActualCostReportItem;			
    
  }
  
  public RCActualCostReportItemProxy toProxy() {
    com.shrct.businessprocess.project.proxy.RCActualCostReportItemProxy proxy = new com.shrct.businessprocess.project.proxy.RCActualCostReportItemProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
